<template>
  <el-tabs
      v-model="editableTabsValue"
      type="border-card"
      editable
      class="demo-tabs"
      tab-position="top"
      @edit="handleTabsEdit"
      @tab-remove="tabRemove"
      @tab-add="tabRemoveAll"
  >
    <template #add-icon>
      <el-tooltip effect="dark" content="关闭全部" placement="top">
        <el-icon><CloseBold /></el-icon>
      </el-tooltip>
    </template>

    <el-tab-pane
        v-for="(item, index) in editableTabs"
        :key="index"
        :label="item.title"
        :name="item.name"
    >
      <template #label>
        <el-badge :is-dot="isCached(item.name)" type="info" class="isCachedBadge">{{
            item.title
          }}</el-badge>
      </template>
    </el-tab-pane>
    <RouterView v-slot="props">
      <keep-alive :include="cachedComponents">
        <component
            :is="formatComponentInstance(props.Component, $route)"
            :key="$route.fullPath"
        ></component>
      </keep-alive>
    </RouterView>
  </el-tabs>
</template>

<script setup>
import { watch, h } from 'vue'
import router from '@/router'
import { usePageTabStore } from '@/stores/pageTab'
import { storeToRefs } from 'pinia'
import { CloseBold } from '@element-plus/icons-vue'
const store = usePageTabStore()
const { del } = store
const { editableTabs, editableTabsValue, cachedComponents, wrapperMap } = storeToRefs(store)

function handleTabsEdit(targetName, action) {
  if (action === 'remove') {
    del(targetName)
  }
}
// 删除标签
function tabRemove(name) {
  let currentRouter = router.resolve(name)
  cachedComponents.value = cachedComponents.value.filter((item) => item != currentRouter.fullPath)
  // 新增：清理工厂缓存
  if (wrapperMap.value.has(currentRouter.fullPath)) {
    wrapperMap.value.delete(currentRouter.fullPath)
  }
}
// 删除全部标签
function tabRemoveAll() {
  cachedComponents.value = []
  wrapperMap.value.clear() // 清空所有缓存
  editableTabs.value = []
  editableTabsValue.value = ''
  router.push('/home')
}
watch(editableTabsValue, async (newTemp) => {
  // 防止删除全部操作导致newTemp为空报错
  if (newTemp) {
    let nowTab = await editableTabs.value.find((item) => item.name === newTemp)
    router.push(nowTab.name)
  }
})

watch(
    () => editableTabs.value.length,
    (newValue, oldValue) => {
      // 新增tab
      if (newValue > oldValue) {
        let lastTab = editableTabs.value[oldValue]
        let currentRouter = router.resolve(lastTab.name)
        cachedComponentsAdd(currentRouter)
      }
    }
)

// 新增缓存
function cachedComponentsAdd(router) {
  if (router.meta && router.meta.keepAlive) {
    if (!cachedComponents.value.includes(router.fullPath)) {
      cachedComponents.value.push(router.fullPath)
    }
  }
}

// 是否有缓存功能
function isCached(name) {
  let currentRouter = router.resolve(name)
  return currentRouter.meta && currentRouter.meta.keepAlive
}

// 将router传个我们的组件重新换一个新的组件，原组件包里面
function formatComponentInstance(component, route) {
  let wrapper
  if (component) {
    const wrapperName = route.fullPath
    if (wrapperMap.value.has(wrapperName)) {
      wrapper = wrapperMap.value.get(wrapperName)
    } else {
      wrapper = {
        name: wrapperName,
        render() {
          return h(component)
        }
      }
      wrapperMap.value.set(wrapperName, wrapper)
    }
    return h(wrapper)
  }
}
</script>
<style scoped>
.demo-tabs {
  height: 100%;
  /* display: flex; */
  /* flex-direction: column; */
}
:deep(.el-tabs__content) {
  /* height: 100%; */
}
.isCachedBadge > :deep(.el-badge__content.is-fixed.is-dot) {
  left: -24px;
}
/* 刪除全部标签按钮 */
:deep(.el-tabs__new-tab) {
  margin-right: 10px;
}
</style>
